<?php
/**
 * This file is part of Hyperf Mall.
 *
 * @link     https://gitee.com/scwlkj/hyperf_mall
 * @contact  hyperf_mall@163.com
 */

namespace App\Repository;

use App\Constants\CartConstants;
use App\Exception\BaseException;
use App\Model\CartModel;
use App\Service\Goods\GoodsService;
use App\Service\Goods\ProductService;
use Hyperf\Di\Annotation\Inject;

class CartRepository extends BaseRepository
{
    /**
     * @Inject
     * @var CartModel
     */
    protected $model;

    /**
     * Notes:添加购物车
     * Author: Bruce.z
     * DateTime: 2022/6/27 16:28
     * @param $data
     * @return \App\Model\BaseModel|bool|\Hyperf\Database\Model\Model
     * @throws BaseException
     */
    public function baseAdd($data)
    {
        $re = $this->getRecords($data['member_id'], $data['goods_id'], $data['product_id']);
        if($re){
            $this->checkProductStock($data);
            return parent::updateByConditions(['id'=>$re['id']], ['number'=>$re['number']+$data['number']]);
        }else{
            $this->checkProductStock($data);
            return parent::baseAdd($data);
        }
    }

    public function getRecords($memberId, $goods_id, $product_id)
    {
        $dbResult = $this->model->select(['id', 'number'])
            ->where('member_id', $memberId)
            ->where('goods_id', $goods_id)
            ->where('product_id', $product_id)
            ->first();

        return $dbResult ? $dbResult->toArray() : [];
    }

    private function checkProductStock($data, $number = 0)
    {
        $stock = GoodsService::getInstance()->getProductStock($data);
        if($stock < $number + $data['number']){
            throw new BaseException(BaseException::BASE_ERROR, CartConstants::getMessage(CartConstants::NOT_ENABLE_STOCK));
        }

        return true;
    }

    /**
     * 购物车数量增加
     * @param $id
     * @param $num
     * @return bool
     */
    public function incNum($id, $num)
    {
        $dbResult = $this->model->where('id', $id)->increment('number', $num);
        return $dbResult ?? false;
    }

    /**
     * 购物车数量减少
     * @param $id
     * @param int $num
     * @return bool
     */
    public function decNum($id, $num = 1)
    {
        $dbResult = $this->model->where('id', $id)->decrement('number', $num);
        return $dbResult ?? false;
    }

    /**
     * 删除
     * @param $ids
     * @param int $member_id
     * @return mixed
     */
    public function removeByIds($ids, int $member_id = 0)
    {
        if(empty($ids)){
            $dbResult = $this->model
                ->where('is_checked', 1)
                ->where('member_id',$member_id)
                ->delete();
        }else{
            $dbResult = $this->model->whereIn('id', $ids)->delete();
        }
        return $dbResult ?? false;
    }

    /**
     * Notes: 编辑数量
     * @param $id
     * @param $num
     * @return bool|int
     */
    public function editNumber($id, $num)
    {
        $dbResult = $this->model->where('id', $id)->update(['number'=>$num]);
        return $dbResult ?? false;
    }

    public function getList(int $member_id):array
    {
        $res = $this->getRows(['member_id'=>$member_id]);
        if(empty($res)) return ['list'=>[],'disable'=>[]];

        // 判断商品是否下架
        $goods_ids = array_column($res, 'goods_id');
        $goods_status = GoodsService::getInstance()->getRows(['id'=>$goods_ids], ['id','is_up','retail_price','stock','name','img']);
        $goods_status = array_column($goods_status, null, 'id');

        $product_ids = array_column($res, 'product_id');
        $product_ids = array_diff($product_ids,[0,'',null]);
        $products = [];
        if(count($product_ids)){
            $products = ProductService::getInstance()->getRows(['id'=>$product_ids], ['id','spec_name','retail_price']);
            $products = array_column($products, null, 'id');
        }
        $return = [];
        $checked_money = $checked_count = $all_count = 0;
        array_map(function ($re)use ($goods_status, &$return, $products,&$checked_money, &$checked_count, &$all_count){
            $goods_id = $re['goods_id'];
            $re = array_merge($goods_status[$goods_id]??[] , $re);

            if($re['product_id']){
                $re['attr_name'] = $products[$re['product_id']]['spec_name'] ?? '';
                $re['retail_price'] = $products[$re['product_id']]['retail_price'] ?? $re['retail_price'];
            }

            $re['is_checked'] = (bool)$re['is_checked'];
            if($re['is_checked']){
                $checked_money = round($re['retail_price'] * $re['number'] + $checked_money, 2);
                $checked_count += $re['number'];
            }
            $all_count += $re['number'];

            if($goods_status[$goods_id]){
                $return['list'][] = $re;
            }else{
                $return['disable'][] = $re;
            }
        }, $res);
        $return['checked_money'] = $checked_money;
        $return['checked_count'] = $checked_count;
        $return['all_count'] = $all_count;

        return $return;
    }

    public function clear(int $member_id):bool
    {
        return $this->model->where('member_id', $member_id)->delete();
    }

    /**
     * Notes: 更新选中状态
     * Author: Bruce.z
     * DateTime: 2022/10/17 17:43
     * @param int $member_id
     * @param int $type
     * @param bool $checked
     * @param int $id
     * @return int
     */
    public function setChecked(int $member_id, int $type = 0, bool $checked = false, int $id = 0): int
    {
        $is_checked = $checked?1:0;
        if($type == 0){//全部
            return $this->model->where('member_id', $member_id)->update(['is_checked'=>$is_checked]);
        }else{
            return $this->model->where('member_id', $member_id)->where('id', $id)->update(['is_checked'=>$is_checked]);
        }
    }

}
